
using Patterns4Net.ArchitectureExplorer.Infrastructure;

namespace Patterns4Net.Tests.ArchitectureExplorer.ViewModels
{
    using System.Linq;
    using Caliburn.Micro;
    using NUnit.Framework;
    using Patterns4Net.ArchitectureExplorer;
    using Patterns4Net.ArchitectureExplorer.ViewModels;
    using Patterns4Net.ArchitectureExplorer.ViewModels.Graph;
    using Patterns4Net.ArchitectureExplorer.ViewModels.Messages;
    using Patterns4Net.ArchitectureExplorer.ViewModels.Results;
    using Patterns4Net.ArchitectureExplorer.ViewModels.Services;

    [TestFixture]
    public class ShellViewModelTest : ViewModelTestBase
    {
        private Moq.Mock<IOpenFileDialog> openFileDialogMock;

        private Moq.Mock<IWindowManager> windowManagerMock;

        private Moq.Mock<IMessageBoxService> messageBoxServiceMock;

        private Moq.Mock<IVisualStudioFilesParser> vsParserMock;

        private ShellViewModel viewModel;

        [SetUp]
        public void SetUp()
        {
            base.SetUpMocks();
            this.openFileDialogMock = new Moq.Mock<IOpenFileDialog>();
            this.openFileDialogMock.Setup(x => x.Clone())
                .Returns(this.openFileDialogMock.Object);

            this.windowManagerMock = new Moq.Mock<IWindowManager>();
            this.messageBoxServiceMock = new Moq.Mock<IMessageBoxService>();
            this.vsParserMock = new Moq.Mock<IVisualStudioFilesParser>();

            this.viewModel = new ShellViewModel(
                this.windowManagerMock.Object,
                this.EventAggregator,
                this.messageBoxServiceMock.Object,
                this.openFileDialogMock.Object,
                this.vsParserMock.Object);
        }

        [Test]
        public void LoadAssembly_Does_Not_Load_Anything_When_OpenFileDialog_Returns_Null()
        {
            this.openFileDialogMock.Setup(x => x.ShowDialog())
                .Returns(() => null);
            var result = this.viewModel.LoadAssembly();
            CollectionAssert.IsEmpty(result);
        }

        [Test]
        public void LoadAssembly_Loads_Assembly_Returned_By_OpenFileDialog()
        {
            this.openFileDialogMock.Setup(x => x.ShowDialog())
                .Returns(() => new[] { "test.dll" });
            this.viewModel.DiagramViewModel = 
                new DiagramViewModel(
                    new Settings(), 
                    new Moq.Mock<IGraphViewModelFactory>().Object,
                    new Moq.Mock<IEventAggregator>().Object);   // we don't want it to actually get the messages.
            this.MessagesSent.Clear();
            var result = this.viewModel.LoadAssembly().ToArray();

            Assert.IsTrue(result.Count() == 3, "ShellViewModel should return 3 results");

            SafeAssert.That(() => result[0].GetType().Name.EndsWith("ProgressShow"), "Result of type ProgressShow is missing");
            Assert.IsInstanceOf<LoadAssembly>(result[1]);
            SafeAssert.That(() => result[2].GetType().Name.EndsWith("ProgressHide"), "Result of type ProgressHide is missing");
            Assert.AreEqual("test.dll", ((LoadAssembly)result[1]).Filename);

            this.AssertPublishedMessage<ZoomToTopLevelMessage>();
        }
    }
}
